import { Terminal } from './../model/clerkDataContext';
import { Injectable } from '@angular/core';
import { Http, Headers, Jsonp, URLSearchParams } from '@angular/http';
import { FNCManager } from './../common/fncManager';
import { ServiceBase } from './serviceBase';

@Injectable()
export class SystemService extends ServiceBase {
    private ldcSvrList: LDCServiceNode[] = [];
    constructor(protected http: Http, protected jsonp: Jsonp) {
        super();
        //TODO:以后可以从配置文件加载
        let fnsSvr = new LDCServiceNode("FNS");
        fnsSvr.errorTip = "请在收银台-设置-本地数据中心中开启“设置本终端为本地数据中心”";
        fnsSvr.describe = "消息通知服务";
        fnsSvr.Check = () => {
            fnsSvr.status = "checking";
            let retryTime = 3;
            let that = this;
            if (FNCManager.Current.IsConnect) {
                fnsSvr.status = "passed";
                that.LDCServiceChangedEvent(fnsSvr);
            } else {
                let timeFns = setInterval(function () {
                    retryTime--;
                    if (FNCManager.Current.IsConnect) {
                        fnsSvr.status = "passed";
                        that.LDCServiceChangedEvent(fnsSvr);
                        clearInterval(timeFns);
                        return;
                    }
                    if (retryTime == 0) {
                        fnsSvr.status = "failed";
                        that.LDCServiceChangedEvent(fnsSvr);
                        clearInterval(timeFns);
                        return;
                    }
                }, 1000);
            }
        }
        let fbsSvr = new LDCServiceNode("FBS");
        fbsSvr.errorTip = "请在收银台-设置-本地数据中心-配置服务中开启“门店业务服务”";
        fbsSvr.describe = "门店业务服务";
        fbsSvr.Check = async () => {
            fbsSvr.status = "checking";
            try {
                let url = "api/system/isOnline";
                let r = await this.Get(url);
                fbsSvr.status = "passed";
                this.LDCServiceChangedEvent(fbsSvr);
            }
            catch (e) {
                fbsSvr.status = "failed";
                this.LDCServiceChangedEvent(fbsSvr);
            }
        }
        this.ldcSvrList.push(fnsSvr);
        this.ldcSvrList.push(fbsSvr);
    }

    /**
     * 校验当前ldc服务的开启状态
     */
    CheckLDCService() {
        this.ldcSvrList.forEach(x => {
            x.Check();
        });
    }
    /**
     * 获取当前ldc服务列表
     * @returns LDCServiceNode
     */
    GetLDCServiceList(): LDCServiceNode[] {
        return this.ldcSvrList;
    }
    /**
     * 绑定终端
     */
    async BindTerminal(name: string) {
        let url = "api/stores/" + this.CurrentStore.id + "/terminals/bind/device";

        //设备信息的获取,从外壳中读取
        let postJson: Terminal = {
            id: "",
            name: name,
            deviceId: "",
            bound: true,
            boundApp: "mclerk",
            hardware: "Nexus",
            deviceType: "handheld",
            platform: "browser",
            platformVersion: "4.2",
            userAgent: "userAgent",
            os: "",
            store: this.CurrentStore
        }
        let device = this.Device;
        if (device) {
            postJson.deviceId = device.deviceId;
            postJson.deviceType = device.deviceType;
            postJson.hardware = device.hardware;
            postJson.platform = device.platform;
            postJson.platformVersion = device.platformVersion;
        }
        let r = await this.PostCloud(url, postJson);
        return r;
    }
    /**
     * 检查绑定的终端是否达到上限
     */
    async CheckTerminalLimt(): Promise<boolean> {
        let url = "api/stores/" + this.CurrentStore.id + "/terminals/limit";

        return this.GetCloud(url);
    }

    /**
     * LDC服务状态变更事件
     */
    LDCServiceChangedEvent: (sender: LDCServiceNode, args?: any) => void;

    async getTerminalName() {
        let url = "api/stores/" + this.CurrentStore.id + "/terminals/terminalname";
        let device = this.Device;
        if (device) {
            url += "?deviceId=" + device.deviceId + "&boundApp=mclerk";
        } else {
            return "";
        }
        return this.GetCloud(url);
    }

    /**
     * 对终端进行解绑
     */
    async unboundTerminial() {
        let url = "api/stores/" + this.CurrentStore.id + "/terminals/" + this.Terminal.id + "/unbound";
        this.PutCloud(url, {});
    }

    /**
     * 检测是否是LDC模式
     * @param {string} ip
     * @returns
     * @memberOf SystemService
     */
    checkIsLDC(ip: string) {
        let port = this.SSL ? 8876 : 8877;
        let result = this.Get("api/about", ip, port);
        return result;
    }

    /**
     * 检测是否开启门店业务服务支持
     */
    async checkIsFBS() {
        let fbsAddress = this.LDCAddress;
        let result = undefined;
        if (fbsAddress) {
            let port = this.SSL ? 8876 : 8877;
            result = await this.Get("api/getStoreInfo", fbsAddress, port);
            if (result) {
                this.CurrentStore = result;
            }
        }
        return result;
    }

    async envHeartCheck() {
        // let LDCAddress = this.LDCAddress;
        // if (!LDCAddress) {
        //     return;
        // }
        // let FNSResult = FNCManager.Current.IsConnect;
        // let LDCResult = false;
        // try {
        //     LDCResult = await this.Get("api/system/isOnline");
        // } catch (error) {
        //     LDCResult = false;
        // }
        // if (FNSResult && LDCResult) {
        //     return true;
        // }
        // return false;
        await this.Get("api/system/isOnline");
    }

    /**
     * 获取版本号
     */
    getVersion() {
        return this.http.get("./version.json").toPromise();
    }
    /**
     * 获取云端最新的版本
     */
    getLatestVersion() {
        let cloudAddress = this.CloudClerkAddress;
        return this.http.get("/version.json?"+new Date().getTime()).toPromise();
    }
}

export class LDCServiceNode {
    private name: string;
    status: string;
    constructor(name: string) {
        this.name = name;
    }
    get Name() {
        return this.name;
    }
    describe: string;
    errorTip: string;
    Check: () => void;
} 